import time
import random
import jieba
import requests
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, TimeoutException

# ==================== 配置项 ====================
DESIRED_CAPS = {
    "platformName": "Android",
    "platformVersion": "13",
    "deviceName": "emulator-5554",
    "appPackage": "com.tencent.mm",
    "appActivity": "com.tencent.mm.ui.LauncherUI",
    "noReset": True,# 保留微信缓存，避免重复登录
    "unicodeKeyboard": True,
    "resetKeyboard": True
}

# 预设问题与回复规则（可扩展）
QUESTIONS = [
    "你好{name}～最近在忙什么？",
    "很高兴认识你{name}，平时喜欢什么类型的活动？",
    "今天天气不错，{name}你那边怎么样？"
]
REPLY_RULES = {
    "工作": ["工作确实辛苦，最近项目顺利吗？", "忙完记得休息呀～"],
    "电影": ["最近有部《奥本海默》挺火的，你看过吗？", "我也喜欢看电影，求推荐～"],
    "学习": ["学习是持续成长的动力，最近在学什么新技能？"],
    "默认": ["我不太懂这个，能再说说吗？"]
}

# 百度AI性别识别API（可选，需申请AK/SK）
BAIDU_AI_CONFIG = {
    "url": "https://aip.baidubce.com/rpc/2.0/nlp/v1/gender",
    "ak": "你的API Key",
    "sk": "你的Secret Key"
}

# ==================== 辅助函数 ====================
def get_access_token():
    """获取百度AI鉴权Token（仅当使用性别识别API时需要）"""
    auth_url = f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={BAIDU_AI_CONFIG['ak']}&client_secret={BAIDU_AI_CONFIG['sk']}"
    res = requests.get(auth_url)
    return res.json().get("access_token")

def analyze_gender(text):
    """分析文本中的性别（优先用API，否则关键词匹配）"""
    # 尝试使用百度AI API
    if BAIDU_AI_CONFIG["ak"]:
        try:
            token = get_access_token()
            res = requests.post(
                f"{BAIDU_AI_CONFIG['url']}?access_token={token}",
                json={"text": text}
            )
            return res.json().get("gender", "未知")  # 返回"male"/"female"/"未知"
        except:
            pass
    # 关键词匹配（备用方案）
    female_words = ["女士", "小姐姐", "妹", "芳", "娜"]
    male_words = ["先生", "小哥哥", "哥", "伟", "强"]
    for word in female_words:
        if word in text:
            return "female"
    for word in male_words:
        if word in text:
            return "male"
    return "未知"

def extract_surname(nickname, verify_msg=""):
    """提取姓氏（优先从验证消息，否则昵称）"""
    text = verify_msg if verify_msg else nickname
    # 尝试从“我是张XX”“姓王”等句式提取
    if "我是" in text:
        idx = text.find("我是") + 2
        return text[idx] if idx < len(text) else nickname[0]
    if "姓" in text:
        idx = text.find("姓") + 1
        return text[idx] if idx < len(text) else nickname[0]
    # 默认取昵称首字
    return nickname[0] if nickname else "朋友"

def get_polite_name(surname, gender):
    """生成拟人化称呼（如“王姐”“李哥”）"""
    if gender == "female":
        return f"{surname}姐" if random.random() > 0.5 else f"{surname}女士"
    elif gender == "male":
        return f"{surname}哥" if random.random() > 0.5 else f"{surname}先生"
    else:
        return f"{surname}朋友"

def generate_reply(user_msg):
    """根据用户消息生成回复（基于关键词匹配）"""
    words = jieba.lcut(user_msg)
    for keyword in REPLY_RULES.keys():
        if keyword in words:
            return random.choice(REPLY_RULES[keyword])
    return random.choice(REPLY_RULES["默认"])

def wait_for_element(driver, locator, timeout=15):
    """等待元素出现（带超时）"""
    try:
        return WebDriverWait(driver, timeout).until(
            EC.presence_of_element_located(locator)
        )
    except TimeoutException:
        return None

# ==================== 核心流程 ====================
def auto_accept_and_chat():
    driver = webdriver.Remote("http://localhost:4723/wd/hub", DESIRED_CAPS)
    driver.implicitly_wait(10)

    try:
        # 步骤1：进入「新的朋友」页面（同前）
        driver.find_element(AppiumBy.XPATH, '//*[@text="通讯录"]').click()
        time.sleep(2)
        driver.find_element(AppiumBy.XPATH, '//*[@text="新的朋友"]').click()
        time.sleep(2)

        # 步骤2：遍历未通过的好友请求
        通过按钮列表 = driver.find_elements(
            AppiumBy.XPATH, '//*[@text="通过验证"]'
        )
        if not 通过按钮列表:
            print("无未通过请求")
            return

        for 按钮 in 通过按钮列表:
            # 滑动到按钮可见
            driver.execute_script("mobile: scrollTo", {"element": 按钮.id})
            按钮.click()
            time.sleep(3)  # 等待跳转聊天界面

            # 步骤3：获取好友信息（昵称、验证消息）
            try:
                # 聊天界面的好友昵称（可能在顶部）
                好友昵称 = wait_for_element(
                    driver, (AppiumBy.ID, "com.tencent.mm:id/az0")  # 顶部昵称ID（需确认）
                ).text
                # 验证消息（可能在聊天记录中第一条）
                验证消息 = wait_for_element(
                    driver, (AppiumBy.XPATH, '//*[@class="android.widget.TextView"][last()]')
                ).text if "验证申请" in driver.page_source else ""
            except:
                好友昵称 = "未知好友"
                验证消息 = ""

            # 步骤4：分析姓氏和性别
            姓氏 = extract_surname(好友昵称, 验证消息)
            性别 = analyze_gender(验证消息 + 好友昵称)
            称呼 = get_polite_name(姓氏, 性别)
            print(f"识别结果：姓氏={姓氏}, 性别={性别}, 称呼={称呼}")

            # 步骤5：自动备注和标签
            try:
                # 进入好友资料页（聊天界面右上角"..."）
                更多按钮 = wait_for_element(
                    driver, (AppiumBy.ID, "com.tencent.mm:id/cj")  # 右上角菜单按钮ID
                )
                更多按钮.click()
                time.sleep(2)
                # 进入「备注和标签」
                备注入口 = wait_for_element(
                    driver, (AppiumBy.XPATH, '//*[@text="备注和标签"]')
                )
                备注入口.click()
                time.sleep(2)
                # 填写备注（如“王姐-客户”）
                备注输入框 = wait_for_element(
                    driver, (AppiumBy.ID, "com.tencent.mm:id/dn")  # 备注输入框ID
                )
                备注输入框.clear()
                备注输入框.send_keys(f"{称呼}-{random.choice(['客户','朋友','测试'])}")
                # 添加标签（假设已有“客户”标签）
                标签按钮 = wait_for_element(
                    driver, (AppiumBy.XPATH, '//*[@text="标签"]/../android.widget.LinearLayout')
                )
                标签按钮.click()
                time.sleep(1)
                # 选择第一个标签（可扩展为动态选择）
                标签选项 = wait_for_element(
                    driver, (AppiumBy.XPATH, '//*[@text="客户"]')
                )
                标签选项.click()
                time.sleep(1)
                # 保存备注
                保存按钮 = wait_for_element(
                    driver, (AppiumBy.XPATH, '//*[@text="保存"]')
                )
                保存按钮.click()
                time.sleep(2)
                print("备注和标签设置完成")
            except Exception as e:
                print(f"备注设置失败：{str(e)}")
                driver.back()  # 返回聊天界面
                time.sleep(2)

            # 步骤6：发送拟人化初始消息
            输入框 = wait_for_element(driver, (AppiumBy.ID, "com.tencent.mm:id/a5_"))  # 输入框ID
            初始消息 = random.choice(QUESTIONS).replace("{name}", 称呼)
            输入框.send_keys(初始消息)
            发送按钮 = wait_for_element(driver, (AppiumBy.XPATH, '//*[@text="发送"]'))
            发送按钮.click()
            print(f"已发送初始消息：{初始消息}")
            time.sleep(2)

            # 步骤7：简单对话（等待用户回复并回应）
            for _ in range(2):  # 模拟回复2轮
                try:
                    # 等待用户消息（最新的非自己的消息）
                    用户消息元素 = wait_for_element(
                        driver, (AppiumBy.XPATH, '//*[@class="android.widget.TextView"][not(contains(@text,"发送"))][last()]'),
                        timeout=10  # 等待10秒用户回复
                    )
                    用户消息 = 用户消息元素.text
                    回复 = generate_reply(用户消息)
                    输入框.send_keys(回复)
                    发送按钮.click()
                    print(f"用户消息：{用户消息} → 回复：{回复}")
                    time.sleep(2)
                except TimeoutException:
                    print("用户未回复，结束对话")
                    break

            # 返回「新的朋友」页面
            driver.back()  # 退出聊天界面
            time.sleep(2)
            driver.back()  # 返回通讯录或新的朋友页面
            time.sleep(2)

        print("所有请求处理完成")
    except Exception as e:
        print(f"脚本异常：{str(e)}")
    finally:
        driver.quit()

# ==================== 执行入口 ====================
if __name__ == "__main__":
    auto_accept_and_chat()